/*
 * Copyright 2008 the Breachwalls OSS project and the Others.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
${template.generateJavaPackageSentence()}

<#list template.generateJavaImportClassSentences() as item>
${item}
<#if !item_has_next>

</#if>
</#list>
/**
 * ${model.getDescription()}.
 * @author todoken
 * @version $Revision$
 */
${template.getClassDefineSentence()}${model.getShortClassName()}${template.generateExtendsClassSentence()} {

    /**
     * シリアルバージョンID.
     */
    private static final long serialVersionUID = ${template.getSerialVersionUID()};

<#if model.isAbstractClass() = true>
    /**
     * ${model.getDescription()}の列挙型表現を構築する.
     * @param value 列挙型の内部値
     * @param name 列挙型の表現値
     */
    protected ${model.getShortClassName()}(final String value, final String name) {
        super(value, name);
    }

<#else>
    /**
     * ${model.getDescription()}のNULL表現.
     */
    public static final ${model.getShortClassName()} NULL = new ${model.getShortClassName()}("", "NULL");

<#list model.getModelProperties() as property>
    /**
     * "${property.getDescription()}"を表現する${model.getDescription()}データタイプ.
     * 内部値は{@value}.
     */
    public static final ${model.getShortClassName()} ${property.getName()} = new ${model.getShortClassName()}("${property.getValue()}", "${property.getDescription()}");

</#list>
    /**
     * ${model.getDescription()}の全リテラル.
     */
    private static final ${template.addImportFullClassName("java.util.List")}<${model.getShortClassName()}> ALL_LITERALS = new ${template.addImportFullClassName("java.util.ArrayList")}<${model.getShortClassName()}>();

    /**
     * ${model.getDescription()}の全リテラルの内部値をキーに持つマップ.
     */
    private static final ${template.addImportFullClassName("java.util.Map")}<String, ${model.getShortClassName()}> MAP_LITERALS;

    static {
<#list model.getModelProperties() as property>
        ALL_LITERALS.add(${property.getName()});
</#list>
        MAP_LITERALS = toMap(ALL_LITERALS.toArray(new ${model.getShortClassName()}[ALL_LITERALS.size()]));
    }

    /**
     * ${model.getDescription()}の列挙型表現を構築する.
     * @param value 列挙型の内部値
     * @param name 列挙型の表現値
     */
    private ${model.getShortClassName()}(final String value, final String name) {
        super(value, name);
    }

<#list model.getModelProperties() as property>
    /**
     * このオブジェクトが${property.getDescription()}であるか確認する.
     * @return このオブジェクトが${property.getDescription()}である場合、TRUEを返す
     */
    public boolean is${template.toMethodName(property.getName())}() {
        return this == ${property.getName()};
    }

</#list>
    /**
     * ${model.getDescription()}の全リテラルを取得する.
     * @return ${model.getDescription()}の全てのリテラル
     */
    public static List<${model.getShortClassName()}> values() {
        return ${template.addImportFullClassName("java.util.Collections")}.unmodifiableList(ALL_LITERALS);
    }

    /**
     * ${model.getDescription()}の内部値をもとに、該当する${model.getDescription()}を取得する.
     * ただし、見つからない場合は${model.getDescription()}のNULLインスタンスを返す.
     * @param value 取得したい${model.getDescription()}のインスタンスの内部値
     * @return 引数と同じ内部値を持つ${model.getDescription()}のインスタンス
     */
    public static ${model.getShortClassName()} valueOf(final String value) {
        ${model.getShortClassName()} v = MAP_LITERALS.get(value);
        if (v == null) {
            v = ${model.getShortClassName()}.NULL;
        }
        return v;
    }
</#if>

}
